{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "ename": "ModuleNotFoundError",
     "evalue": "No module named 'google.colab'",
     "output_type": "error",
     "traceback": [
      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1;31mModuleNotFoundError\u001b[0m                       Traceback (most recent call last)",
      "\u001b[1;32m<ipython-input-1-35bef2f5146d>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m\u001b[0m\n\u001b[0;32m      1\u001b[0m \u001b[1;31m# this mounts your Google Drive to the Colab VM.\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 2\u001b[1;33m \u001b[1;32mfrom\u001b[0m \u001b[0mgoogle\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mcolab\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mdrive\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m      3\u001b[0m \u001b[0mdrive\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mmount\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m'/content/drive'\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mforce_remount\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;32mTrue\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m      4\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m      5\u001b[0m \u001b[1;31m# enter the foldername in your Drive where you have saved the unzipped\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
      "\u001b[1;31mModuleNotFoundError\u001b[0m: No module named 'google.colab'"
     ]
    }
   ],
   "source": [
    "# this mounts your Google Drive to the Colab VM.\n",
    "from google.colab import drive\n",
    "drive.mount('/content/drive', force_remount=True)\n",
    "\n",
    "# enter the foldername in your Drive where you have saved the unzipped\n",
    "# assignment folder, e.g. 'cs231n/assignments/assignment3/'\n",
    "FOLDERNAME = None\n",
    "assert FOLDERNAME is not None, \"[!] Enter the foldername.\"\n",
    "\n",
    "# now that we've mounted your Drive, this ensures that\n",
    "# the Python interpreter of the Colab VM can load\n",
    "# python files from within it.\n",
    "import sys\n",
    "sys.path.append('/content/drive/My Drive/{}'.format(FOLDERNAME))\n",
    "\n",
    "# this downloads the CIFAR-10 dataset to your Drive\n",
    "# if it doesn't already exist.\n",
    "%cd drive/My\\ Drive/$FOLDERNAME/cs231n/datasets/\n",
    "!bash get_datasets.sh\n",
    "%cd /content"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "tags": [
     "pdf-title"
    ]
   },
   "source": [
    "# Fully-Connected Neural Nets\n",
    "In the previous homework you implemented a fully-connected two-layer neural network on CIFAR-10. The implementation was simple but not very modular since the loss and gradient were computed in a single monolithic function. This is manageable for a simple two-layer network, but would become impractical as we move to bigger models. Ideally we want to build networks using a more modular design so that we can implement different layer types in isolation and then snap them together into models with different architectures."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "tags": [
     "pdf-ignore"
    ]
   },
   "source": [
    "In this exercise we will implement fully-connected networks using a more modular approach. For each layer we will implement a `forward` and a `backward` function. The `forward` function will receive inputs, weights, and other parameters and will return both an output and a `cache` object storing data needed for the backward pass, like this:\n",
    "\n",
    "```python\n",
    "def layer_forward(x, w):\n",
    "  \"\"\" Receive inputs x and weights w \"\"\"\n",
    "  # Do some computations ...\n",
    "  z = # ... some intermediate value\n",
    "  # Do some more computations ...\n",
    "  out = # the output\n",
    "   \n",
    "  cache = (x, w, z, out) # Values we need to compute gradients\n",
    "   \n",
    "  return out, cache\n",
    "```\n",
    "\n",
    "The backward pass will receive upstream derivatives and the `cache` object, and will return gradients with respect to the inputs and weights, like this:\n",
    "\n",
    "```python\n",
    "def layer_backward(dout, cache):\n",
    "  \"\"\"\n",
    "  Receive dout (derivative of loss with respect to outputs) and cache,\n",
    "  and compute derivative with respect to inputs.\n",
    "  \"\"\"\n",
    "  # Unpack cache values\n",
    "  x, w, z, out = cache\n",
    "  \n",
    "  # Use values in cache to compute derivatives\n",
    "  dx = # Derivative of loss with respect to x\n",
    "  dw = # Derivative of loss with respect to w\n",
    "  \n",
    "  return dx, dw\n",
    "```\n",
    "\n",
    "After implementing a bunch of layers this way, we will be able to easily combine them to build classifiers with different architectures.\n",
    "\n",
    "In addition to implementing fully-connected networks of arbitrary depth, we will also explore different update rules for optimization, and introduce Dropout as a regularizer and Batch/Layer Normalization as a tool to more efficiently optimize deep networks.\n",
    "  "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "tags": [
     "pdf-ignore"
    ]
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "=========== You can safely ignore the message below if you are NOT working on ConvolutionalNetworks.ipynb ===========\n",
      "\tYou will need to compile a Cython extension for a portion of this assignment.\n",
      "\tThe instructions to do this will be given in a section of the notebook below.\n",
      "\tThere will be an option for Colab users and another for Jupyter (local) users.\n"
     ]
    }
   ],
   "source": [
    "# As usual, a bit of setup\n",
    "from __future__ import print_function\n",
    "import time\n",
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "from cs231n.classifiers.fc_net import *\n",
    "from cs231n.data_utils import get_CIFAR10_data\n",
    "from cs231n.gradient_check import eval_numerical_gradient, eval_numerical_gradient_array\n",
    "from cs231n.solver import Solver\n",
    "\n",
    "%matplotlib inline\n",
    "plt.rcParams['figure.figsize'] = (10.0, 8.0) # set default size of plots\n",
    "plt.rcParams['image.interpolation'] = 'nearest'\n",
    "plt.rcParams['image.cmap'] = 'gray'\n",
    "\n",
    "# for auto-reloading external modules\n",
    "# see http://stackoverflow.com/questions/1907993/autoreload-of-modules-in-ipython\n",
    "%load_ext autoreload\n",
    "%autoreload 2\n",
    "\n",
    "def rel_error(x, y):\n",
    "  \"\"\" returns relative error \"\"\"\n",
    "  return np.max(np.abs(x - y) / (np.maximum(1e-8, np.abs(x) + np.abs(y))))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "tags": [
     "pdf-ignore"
    ]
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "('X_train: ', (49000, 3, 32, 32))\n",
      "('y_train: ', (49000,))\n",
      "('X_val: ', (1000, 3, 32, 32))\n",
      "('y_val: ', (1000,))\n",
      "('X_test: ', (1000, 3, 32, 32))\n",
      "('y_test: ', (1000,))\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "dict"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Load the (preprocessed) CIFAR10 data.\n",
    "\n",
    "data = get_CIFAR10_data()\n",
    "for k, v in list(data.items()):\n",
    "  print(('%s: ' % k, v.shape))\n",
    "type(data)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Affine layer: forward\n",
    "Open the file `cs231n/layers.py` and implement the `affine_forward` function.\n",
    "\n",
    "Once you are done you can test your implementaion by running the following:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(2, 4, 5, 6)\n",
      "Testing affine_forward function:\n",
      "difference:  9.769849468192957e-10\n"
     ]
    }
   ],
   "source": [
    "# Test the affine_forward function\n",
    "\n",
    "num_inputs = 2\n",
    "input_shape = (4, 5, 6)\n",
    "output_dim = 3\n",
    "\n",
    "input_size = num_inputs * np.prod(input_shape)#prod计算数组内部的积\n",
    "weight_size = output_dim * np.prod(input_shape)\n",
    "\n",
    "x = np.linspace(-0.1, 0.5, num=input_size).reshape(num_inputs, *input_shape)#加星号会把变量变成一个个独立的元素\n",
    "w = np.linspace(-0.2, 0.3, num=weight_size).reshape(np.prod(input_shape), output_dim)\n",
    "print(x.shape)\n",
    "b = np.linspace(-0.3, 0.1, num=output_dim)\n",
    "\n",
    "out, _ = affine_forward(x, w, b)\n",
    "correct_out = np.array([[ 1.49834967,  1.70660132,  1.91485297],\n",
    "                        [ 3.25553199,  3.5141327,   3.77273342]])\n",
    "\n",
    "# Compare your output with ours. The error should be around e-9 or less.\n",
    "print('Testing affine_forward function:')\n",
    "print('difference: ', rel_error(out, correct_out))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Affine layer: backward\n",
    "Now implement the `affine_backward` function and test your implementation using numeric gradient checking."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Testing affine_backward function:\n",
      "dx error:  5.399100368651805e-11\n",
      "dw error:  9.904211865398145e-11\n",
      "db error:  2.4122867568119087e-11\n"
     ]
    }
   ],
   "source": [
    "# Test the affine_backward function\n",
    "np.random.seed(231)\n",
    "x = np.random.randn(10, 2, 3)\n",
    "w = np.random.randn(6, 5)\n",
    "b = np.random.randn(5)\n",
    "dout = np.random.randn(10, 5)\n",
    "\n",
    "dx_num = eval_numerical_gradient_array(lambda x: affine_forward(x, w, b)[0], x, dout)\n",
    "dw_num = eval_numerical_gradient_array(lambda w: affine_forward(x, w, b)[0], w, dout)\n",
    "db_num = eval_numerical_gradient_array(lambda b: affine_forward(x, w, b)[0], b, dout)\n",
    "\n",
    "_, cache = affine_forward(x, w, b)\n",
    "dx, dw, db = affine_backward(dout, cache)\n",
    "\n",
    "# The error should be around e-10 or less\n",
    "print('Testing affine_backward function:')\n",
    "print('dx error: ', rel_error(dx_num, dx))\n",
    "print('dw error: ', rel_error(dw_num, dw))\n",
    "print('db error: ', rel_error(db_num, db))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 47,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.])"
      ]
     },
     "execution_count": 47,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a=np.random.rand(16)\n",
    "a.reshape(4,-1)\n",
    "a[np.where(a<0)]\n",
    "b=a\n",
    "b[:]=0\n",
    "a"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# ReLU activation: forward\n",
    "Implement the forward pass for the ReLU activation function in the `relu_forward` function and test your implementation using the following:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Testing relu_forward function:\n",
      "difference:  4.999999798022158e-08\n"
     ]
    }
   ],
   "source": [
    "# Test the relu_forward function\n",
    "\n",
    "x = np.linspace(-0.5, 0.5, num=12).reshape(3, 4)\n",
    "\n",
    "out, _ = relu_forward(x)\n",
    "correct_out = np.array([[ 0.,          0.,          0.,          0.,        ],\n",
    "                        [ 0.,          0.,          0.04545455,  0.13636364,],\n",
    "                        [ 0.22727273,  0.31818182,  0.40909091,  0.5,       ]])\n",
    "\n",
    "# Compare your output with ours. The error should be on the order of e-8\n",
    "print('Testing relu_forward function:')\n",
    "print('difference: ', rel_error(out, correct_out))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# ReLU activation: backward\n",
    "Now implement the backward pass for the ReLU activation function in the `relu_backward` function and test your implementation using numeric gradient checking:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[-0.22557183 -1.1928829   0.          0.          0.          0.\n",
      "   0.         -0.35229594  0.          0.        ]\n",
      " [ 0.         -0.84338097  0.          0.85434757 -0.90377338 -1.0525584\n",
      "   0.          0.18083726 -0.4125417   1.22913948]\n",
      " [-0.97791748 -0.63978524 -0.00880963  0.36213294  0.35148162  0.\n",
      "  -0.84272962  0.         -2.39079478  0.88256212]\n",
      " [-1.12082008  0.12416778  0.         -1.62701704  0.          2.00862337\n",
      "   0.         -0.86943856  0.          0.        ]\n",
      " [ 0.          0.          0.         -0.67498124  0.         -0.11970425\n",
      "   0.59700586 -2.0399063   0.         -1.61700346]\n",
      " [ 0.          0.          1.97009461 -0.81967191  0.42367521 -1.83570698\n",
      "   0.          0.          0.          0.        ]\n",
      " [ 0.          2.13935149 -0.77429891  0.          0.          0.\n",
      "   0.          0.          0.59190367 -0.56016357]\n",
      " [ 0.          0.          0.          0.          0.37364743 -0.26051388\n",
      "   0.          0.          0.          0.        ]\n",
      " [ 0.          0.          0.         -1.74506882 -0.2476718   0.\n",
      "   1.09734348  0.          0.         -0.32986357]\n",
      " [ 0.         -0.00396778  0.          0.          0.          0.\n",
      "  -0.9308637   0.          0.         -1.1058167 ]]\n",
      "Testing relu_backward function:\n",
      "dx error:  3.2756349136310288e-12\n"
     ]
    }
   ],
   "source": [
    "np.random.seed(231)\n",
    "x = np.random.randn(10, 10)\n",
    "dout = np.random.randn(*x.shape)\n",
    "\n",
    "dx_num = eval_numerical_gradient_array(lambda x: relu_forward(x)[0], x, dout)\n",
    "\n",
    "_, cache = relu_forward(x)\n",
    "dx = relu_backward(dout, cache)\n",
    "\n",
    "# The error should be on the order of e-12\n",
    "print('Testing relu_backward function:')\n",
    "print('dx error: ', rel_error(dx_num, dx))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "tags": [
     "pdf-inline"
    ]
   },
   "source": [
    "## Inline Question 1: \n",
    "\n",
    "We've only asked you to implement ReLU, but there are a number of different activation functions that one could use in neural networks, each with its pros and cons. In particular, an issue commonly seen with activation functions is getting zero (or close to zero) gradient flow during backpropagation. Which of the following activation functions have this problem? If you consider these functions in the one dimensional case, what types of input would lead to this behaviour?\n",
    "1. Sigmoid\n",
    "2. ReLU\n",
    "3. Leaky ReLU\n",
    "\n",
    "## Answer:\n",
    "[Relu]\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# \"Sandwich\" layers\n",
    "There are some common patterns of layers that are frequently used in neural nets. For example, affine layers are frequently followed by a ReLU nonlinearity. To make these common patterns easy, we define several convenience layers in the file `cs231n/layer_utils.py`.\n",
    "\n",
    "For now take a look at the `affine_relu_forward` and `affine_relu_backward` functions, and run the following to numerically gradient check the backward pass:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 48,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[ 0.          0.          0.          0.          0.98687019  0.\n",
      "   0.119619    2.13935149  0.         -0.42011785]\n",
      " [ 0.         -1.0141586  -2.30296116  0.          0.          0.\n",
      "   0.          0.         -0.93426589  0.        ]]\n",
      "Testing affine_relu_forward and affine_relu_backward:\n",
      "dx error:  2.299579177309368e-11\n",
      "dw error:  8.162011105764925e-11\n",
      "db error:  7.826724021458994e-12\n"
     ]
    }
   ],
   "source": [
    "from cs231n.layer_utils import affine_relu_forward, affine_relu_backward\n",
    "np.random.seed(231)\n",
    "x = np.random.randn(2, 3, 4)\n",
    "w = np.random.randn(12, 10)\n",
    "b = np.random.randn(10)\n",
    "dout = np.random.randn(2, 10)\n",
    "\n",
    "out, cache = affine_relu_forward(x, w, b)\n",
    "dx, dw, db = affine_relu_backward(dout, cache)\n",
    "\n",
    "dx_num = eval_numerical_gradient_array(lambda x: affine_relu_forward(x, w, b)[0], x, dout)\n",
    "dw_num = eval_numerical_gradient_array(lambda w: affine_relu_forward(x, w, b)[0], w, dout)\n",
    "db_num = eval_numerical_gradient_array(lambda b: affine_relu_forward(x, w, b)[0], b, dout)\n",
    "\n",
    "# Relative error should be around e-10 or less\n",
    "print('Testing affine_relu_forward and affine_relu_backward:')\n",
    "print('dx error: ', rel_error(dx_num, dx))\n",
    "print('dw error: ', rel_error(dw_num, dw))\n",
    "print('db error: ', rel_error(db_num, db))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Loss layers: Softmax and SVM\n",
    "You implemented these loss functions in the last assignment, so we'll give them to you for free here. You should still make sure you understand how they work by looking at the implementations in `cs231n/layers.py`.\n",
    "\n",
    "You can make sure that the implementations are correct by running the following:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 49,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Testing svm_loss:\n",
      "loss:  8.999602749096233\n",
      "dx error:  1.4021566006651672e-09\n",
      "\n",
      "Testing softmax_loss:\n",
      "loss:  2.302545844500738\n",
      "dx error:  9.384673161989355e-09\n"
     ]
    }
   ],
   "source": [
    "np.random.seed(231)\n",
    "num_classes, num_inputs = 10, 50\n",
    "x = 0.001 * np.random.randn(num_inputs, num_classes)\n",
    "y = np.random.randint(num_classes, size=num_inputs)\n",
    "\n",
    "dx_num = eval_numerical_gradient(lambda x: svm_loss(x, y)[0], x, verbose=False)\n",
    "loss, dx = svm_loss(x, y)\n",
    "\n",
    "# Test svm_loss function. Loss should be around 9 and dx error should be around the order of e-9\n",
    "print('Testing svm_loss:')\n",
    "print('loss: ', loss)\n",
    "print('dx error: ', rel_error(dx_num, dx))\n",
    "\n",
    "dx_num = eval_numerical_gradient(lambda x: softmax_loss(x, y)[0], x, verbose=False)\n",
    "loss, dx = softmax_loss(x, y)\n",
    "\n",
    "# Test softmax_loss function. Loss should be close to 2.3 and dx error should be around e-8\n",
    "print('\\nTesting softmax_loss:')\n",
    "print('loss: ', loss)\n",
    "print('dx error: ', rel_error(dx_num, dx))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Two-layer network\n",
    "In the previous assignment you implemented a two-layer neural network in a single monolithic class. Now that you have implemented modular versions of the necessary layers, you will reimplement the two layer network using these modular implementations.\n",
    "\n",
    "Open the file `cs231n/classifiers/fc_net.py` and complete the implementation of the `TwoLayerNet` class. This class will serve as a model for the other networks you will implement in this assignment, so read through it to make sure you understand the API. You can run the cell below to test your implementation."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 66,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Testing initialization ... \n",
      "Testing test-time forward pass ... \n",
      "Testing training loss (no regularization)\n",
      "Running numeric gradient check with reg =  0.0\n",
      "W1 relative error: 1.83e-08\n",
      "W2 relative error: 3.12e-10\n",
      "b1 relative error: 9.83e-09\n",
      "b2 relative error: 4.33e-10\n",
      "Running numeric gradient check with reg =  0.7\n",
      "W1 relative error: 2.53e-07\n",
      "W2 relative error: 2.85e-08\n",
      "b1 relative error: 1.56e-08\n",
      "b2 relative error: 7.76e-10\n"
     ]
    }
   ],
   "source": [
    "np.random.seed(231)\n",
    "N, D, H, C = 3, 5, 50, 7\n",
    "X = np.random.randn(N, D)\n",
    "y = np.random.randint(C, size=N)\n",
    "\n",
    "std = 1e-3\n",
    "model = TwoLayerNet(input_dim=D, hidden_dim=H, num_classes=C, weight_scale=std)\n",
    "\n",
    "print('Testing initialization ... ')\n",
    "W1_std = abs(model.params['W1'].std() - std)\n",
    "b1 = model.params['b1']\n",
    "W2_std = abs(model.params['W2'].std() - std)\n",
    "b2 = model.params['b2']\n",
    "assert W1_std < std / 10, 'First layer weights do not seem right'\n",
    "assert np.all(b1 == 0), 'First layer biases do not seem right'\n",
    "assert W2_std < std / 10, 'Second layer weights do not seem right'\n",
    "assert np.all(b2 == 0), 'Second layer biases do not seem right'\n",
    "\n",
    "#检查向前传播\n",
    "print('Testing test-time forward pass ... ')\n",
    "model.params['W1'] = np.linspace(-0.7, 0.3, num=D*H).reshape(D, H)\n",
    "model.params['b1'] = np.linspace(-0.1, 0.9, num=H)\n",
    "model.params['W2'] = np.linspace(-0.3, 0.4, num=H*C).reshape(H, C)\n",
    "model.params['b2'] = np.linspace(-0.9, 0.1, num=C)\n",
    "X = np.linspace(-5.5, 4.5, num=N*D).reshape(D, N).T\n",
    "scores = model.loss(X)\n",
    "correct_scores = np.asarray(\n",
    "  [[11.53165108,  12.2917344,   13.05181771,  13.81190102,  14.57198434, 15.33206765,  16.09215096],\n",
    "   [12.05769098,  12.74614105,  13.43459113,  14.1230412,   14.81149128, 15.49994135,  16.18839143],\n",
    "   [12.58373087,  13.20054771,  13.81736455,  14.43418138,  15.05099822, 15.66781506,  16.2846319 ]])\n",
    "scores_diff = np.abs(scores - correct_scores).sum()\n",
    "assert scores_diff < 1e-6, 'Problem with test-time forward pass'\n",
    "\n",
    "print('Testing training loss (no regularization)')\n",
    "y = np.asarray([0, 5, 1])\n",
    "loss, grads = model.loss(X, y)\n",
    "correct_loss = 3.4702243556\n",
    "assert abs(loss - correct_loss) < 1e-10, 'Problem with training-time loss'\n",
    "\n",
    "model.reg = 1.0\n",
    "loss, grads = model.loss(X, y)\n",
    "correct_loss = 26.5948426952\n",
    "assert abs(loss - correct_loss) < 1e-10, 'Problem with regularization loss'\n",
    "\n",
    "# Errors should be around e-7 or less\n",
    "for reg in [0.0, 0.7]:\n",
    "  print('Running numeric gradient check with reg = ', reg)\n",
    "  model.reg = reg\n",
    "  loss, grads = model.loss(X, y)\n",
    "\n",
    "  for name in sorted(grads):\n",
    "    f = lambda _: model.loss(X, y)[0]\n",
    "    grad_num = eval_numerical_gradient(f, model.params[name], verbose=False)\n",
    "    print('%s relative error: %.2e' % (name, rel_error(grad_num, grads[name])))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Solver\n",
    "In the previous assignment, the logic for training models was coupled to the models themselves. Following a more modular design, for this assignment we have split the logic for training models into a separate class.\n",
    "\n",
    "Open the file `cs231n/solver.py` and read through it to familiarize yourself with the API. After doing so, use a `Solver` instance to train a `TwoLayerNet` that achieves at least `50%` accuracy on the validation set."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 67,
   "metadata": {
    "id": "tln_solver_accuracy"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(Iteration 1 / 4900) loss: 2.307251\n",
      "(Epoch 0 / 10) train acc: 0.122000; val_acc: 0.135000\n",
      "(Iteration 101 / 4900) loss: 1.904633\n",
      "(Iteration 201 / 4900) loss: 2.002815\n",
      "(Iteration 301 / 4900) loss: 1.939815\n",
      "(Iteration 401 / 4900) loss: 1.692869\n",
      "(Epoch 1 / 10) train acc: 0.360000; val_acc: 0.356000\n",
      "(Iteration 501 / 4900) loss: 1.660565\n",
      "(Iteration 601 / 4900) loss: 1.880848\n",
      "(Iteration 701 / 4900) loss: 1.880259\n",
      "(Iteration 801 / 4900) loss: 1.757635\n",
      "(Iteration 901 / 4900) loss: 1.628229\n",
      "(Epoch 2 / 10) train acc: 0.403000; val_acc: 0.387000\n",
      "(Iteration 1001 / 4900) loss: 1.708118\n",
      "(Iteration 1101 / 4900) loss: 1.717468\n",
      "(Iteration 1201 / 4900) loss: 2.001214\n",
      "(Iteration 1301 / 4900) loss: 1.804594\n",
      "(Iteration 1401 / 4900) loss: 1.604010\n",
      "(Epoch 3 / 10) train acc: 0.407000; val_acc: 0.378000\n",
      "(Iteration 1501 / 4900) loss: 1.621277\n",
      "(Iteration 1601 / 4900) loss: 1.545448\n",
      "(Iteration 1701 / 4900) loss: 1.708754\n",
      "(Iteration 1801 / 4900) loss: 1.850482\n",
      "(Iteration 1901 / 4900) loss: 1.827691\n",
      "(Epoch 4 / 10) train acc: 0.420000; val_acc: 0.403000\n",
      "(Iteration 2001 / 4900) loss: 1.735751\n",
      "(Iteration 2101 / 4900) loss: 1.697524\n",
      "(Iteration 2201 / 4900) loss: 1.693520\n",
      "(Iteration 2301 / 4900) loss: 1.717487\n",
      "(Iteration 2401 / 4900) loss: 1.796323\n",
      "(Epoch 5 / 10) train acc: 0.400000; val_acc: 0.393000\n",
      "(Iteration 2501 / 4900) loss: 1.748341\n",
      "(Iteration 2601 / 4900) loss: 1.694136\n",
      "(Iteration 2701 / 4900) loss: 1.560442\n",
      "(Iteration 2801 / 4900) loss: 1.719854\n",
      "(Iteration 2901 / 4900) loss: 1.644606\n",
      "(Epoch 6 / 10) train acc: 0.403000; val_acc: 0.420000\n",
      "(Iteration 3001 / 4900) loss: 1.782474\n",
      "(Iteration 3101 / 4900) loss: 1.790161\n",
      "(Iteration 3201 / 4900) loss: 1.689230\n",
      "(Iteration 3301 / 4900) loss: 1.727900\n",
      "(Iteration 3401 / 4900) loss: 1.826570\n",
      "(Epoch 7 / 10) train acc: 0.407000; val_acc: 0.399000\n",
      "(Iteration 3501 / 4900) loss: 1.662645\n",
      "(Iteration 3601 / 4900) loss: 1.582069\n",
      "(Iteration 3701 / 4900) loss: 1.926454\n",
      "(Iteration 3801 / 4900) loss: 1.687454\n",
      "(Iteration 3901 / 4900) loss: 1.678703\n",
      "(Epoch 8 / 10) train acc: 0.417000; val_acc: 0.400000\n",
      "(Iteration 4001 / 4900) loss: 1.704406\n",
      "(Iteration 4101 / 4900) loss: 1.837995\n",
      "(Iteration 4201 / 4900) loss: 1.684002\n",
      "(Iteration 4301 / 4900) loss: 1.636742\n",
      "(Iteration 4401 / 4900) loss: 1.726430\n",
      "(Epoch 9 / 10) train acc: 0.433000; val_acc: 0.409000\n",
      "(Iteration 4501 / 4900) loss: 1.453405\n",
      "(Iteration 4601 / 4900) loss: 1.879645\n",
      "(Iteration 4701 / 4900) loss: 1.534970\n",
      "(Iteration 4801 / 4900) loss: 1.539189\n",
      "(Epoch 10 / 10) train acc: 0.413000; val_acc: 0.416000\n"
     ]
    }
   ],
   "source": [
    "model = TwoLayerNet()\n",
    "solver = None\n",
    "\n",
    "##############################################################################\n",
    "# TODO: Use a Solver instance to train a TwoLayerNet that achieves at least  #\n",
    "# 50% accuracy on the validation set.                                        #\n",
    "##############################################################################\n",
    "# *****START OF YOUR CODE (DO NOT DELETE/MODIFY THIS LINE)*****\n",
    "solver = Solver(model, data,\n",
    "                    update_rule='sgd',\n",
    "                    optim_config={\n",
    "                      'learning_rate': 1e-3,\n",
    "                    },\n",
    "                    lr_decay=0.95,\n",
    "                    num_epochs=10, batch_size=100,\n",
    "                    print_every=100,verbose=True)\n",
    "pass\n",
    "solver.train()\n",
    "# *****END OF YOUR CODE (DO NOT DELETE/MODIFY THIS LINE)*****\n",
    "##############################################################################\n",
    "#                             END OF YOUR CODE                               #\n",
    "##############################################################################"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 68,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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627cuHFceOGFnHnmmfj9fsaPH9/x2KWXXsp//ud/Mn/+fGbNmsWSJUsG7XUHQoGuL9vWwJ+/BoGIntz962HbGlYdOwctE8AAAAm3SURBVIfmQIgvaKkCEREREZERZ9WqVVG3p6Sk8Mwzz0R9rP08udzcXN5+++2O7bfeeuug19dO59D15YW7uoY5gLZm7Av/yq9f28fymXnMmpDpTm0iIiIiIjLqKdD1pbail+2VVNe18MVlxdEfFxERERERGQYKdH3Jir4UwRGTy+wJmSw9I3eYCxIREREREemkQNeXi+4EX9fV3IPeVL7f8nFuXFqMMVpIXERERERE3KNJUfoy/xrnun2Wy6wifum9ng2e87h3QYG7tYmIiIiIyKinQNef+dd0BLtdh+r495+s5bYVU0lJ0kLiIiIiIiLiLrVcnoKH1pXh93m5fvFkt0sREREREZF229bAj8+E72U719vWDOvLZ2RkDOvrRdIIXT+e3FrZseq8BZaeMY7stGS3yxIREREREei5dnRtuXMfOk+hGsEU6Prw5NZK7nh8O02BYMe2zftO8OTWykFdiV5ERERERHrxzO1waHvvj1dshmBL122BJvjTLbDlN9GPmXAWXHZ3r0/5ne98hylTpvCVr3wFgO9973sYY1i7di0nTpwgEAjwb//2b6xcufJUf5pBp5bLPtz77K4uYQ6gpS3Evc/ucqkiERERERHponuY6297DK699loeffTRjvtr1qzhhhtu4IknnuCNN97gpZde4tvf/jbW2gG/xmDRCF0fqmqaTmm7iIiIiIgMsj5G0gDnnLna8p7bsybBDX8d0EsuXLiQI0eOUFVVRXV1NTk5OUycOJFvfvObrF27Fo/HQ2VlJYcPH2bChAkDeo3BokDXh4JsP5VRwltBtj/K3iIiIiIiMuwuurPrOXTgrCV90Z2n9bRXX301jz32GIcOHeLaa6/lkUceobq6mi1btuDz+Zg6dSrNzc2nWfzpU8tlH25bMQu/r+vyBH6fl9tWzHKpIhERERER6WL+NXDF/c6IHMa5vuL+054Q5dprr2X16tU89thjXH311dTW1pKfn4/P5+Oll15i//79g1P/adIIXR/aJz5pn+WyINvPbStmaUIUEREREZF4ErF29GCZN28edXV1FBYWMnHiRK6//nquuOIKSkpKWLBgAbNnzx7U1xsoBbp+XLWw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\n",
      "text/plain": [
       "<Figure size 1080x864 with 2 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "# Run this cell to visualize training loss and train / val accuracy\n",
    "\n",
    "plt.subplot(2, 1, 1)\n",
    "plt.title('Training loss')\n",
    "plt.plot(solver.loss_history, 'o')\n",
    "plt.xlabel('Iteration')\n",
    "\n",
    "plt.subplot(2, 1, 2)\n",
    "plt.title('Accuracy')\n",
    "plt.plot(solver.train_acc_history, '-o', label='train')\n",
    "plt.plot(solver.val_acc_history, '-o', label='val')\n",
    "plt.plot([0.5] * len(solver.val_acc_history), 'k--')\n",
    "plt.xlabel('Epoch')\n",
    "plt.legend(loc='lower right')\n",
    "plt.gcf().set_size_inches(15, 12)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Multilayer network\n",
    "Next you will implement a fully-connected network with an arbitrary number of hidden layers.\n",
    "\n",
    "Read through the `FullyConnectedNet` class in the file `cs231n/classifiers/fc_net.py`.\n",
    "\n",
    "Implement the initialization, the forward pass, and the backward pass. For the moment don't worry about implementing dropout or batch/layer normalization; we will add those features soon."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Initial loss and gradient check\n",
    "\n",
    "As a sanity check, run the following to check the initial loss and to gradient check the network both with and without regularization. Do the initial losses seem reasonable?\n",
    "\n",
    "For gradient checking, you should expect to see errors around 1e-7 or less."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "np.random.seed(231)\n",
    "N, D, H1, H2, C = 2, 15, 20, 30, 10\n",
    "X = np.random.randn(N, D)\n",
    "y = np.random.randint(C, size=(N,))\n",
    "\n",
    "for reg in [0, 3.14]:\n",
    "  print('Running check with reg = ', reg)\n",
    "  model = FullyConnectedNet([H1, H2], input_dim=D, num_classes=C,\n",
    "                            reg=reg, weight_scale=5e-2, dtype=np.float64)\n",
    "\n",
    "  loss, grads = model.loss(X, y)\n",
    "  print('Initial loss: ', loss)\n",
    "  \n",
    "  # Most of the errors should be on the order of e-7 or smaller.   \n",
    "  # NOTE: It is fine however to see an error for W2 on the order of e-5\n",
    "  # for the check when reg = 0.0\n",
    "  for name in sorted(grads):\n",
    "    f = lambda _: model.loss(X, y)[0]\n",
    "    grad_num = eval_numerical_gradient(f, model.params[name], verbose=False, h=1e-5)\n",
    "    print('%s relative error: %.2e' % (name, rel_error(grad_num, grads[name])))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "As another sanity check, make sure you can overfit a small dataset of 50 images. First we will try a three-layer network with 100 units in each hidden layer. In the following cell, tweak the **learning rate** and **weight initialization scale** to overfit and achieve 100% training accuracy within 20 epochs."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "scrolled": false
   },
   "outputs": [],
   "source": [
    "# TODO: Use a three-layer Net to overfit 50 training examples by \n",
    "# tweaking just the learning rate and initialization scale.\n",
    "\n",
    "num_train = 50\n",
    "small_data = {\n",
    "  'X_train': data['X_train'][:num_train],\n",
    "  'y_train': data['y_train'][:num_train],\n",
    "  'X_val': data['X_val'],\n",
    "  'y_val': data['y_val'],\n",
    "}\n",
    "\n",
    "weight_scale = 1e-2   # Experiment with this!\n",
    "learning_rate = 1e-4  # Experiment with this!\n",
    "model = FullyConnectedNet([100, 100],\n",
    "              weight_scale=weight_scale, dtype=np.float64)\n",
    "solver = Solver(model, small_data,\n",
    "                print_every=10, num_epochs=20, batch_size=25,\n",
    "                update_rule='sgd',\n",
    "                optim_config={\n",
    "                  'learning_rate': learning_rate,\n",
    "                }\n",
    "         )\n",
    "solver.train()\n",
    "\n",
    "plt.plot(solver.loss_history, 'o')\n",
    "plt.title('Training loss history')\n",
    "plt.xlabel('Iteration')\n",
    "plt.ylabel('Training loss')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now try to use a five-layer network with 100 units on each layer to overfit 50 training examples. Again, you will have to adjust the learning rate and weight initialization scale, but you should be able to achieve 100% training accuracy within 20 epochs."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# TODO: Use a five-layer Net to overfit 50 training examples by \n",
    "# tweaking just the learning rate and initialization scale.\n",
    "\n",
    "num_train = 50\n",
    "small_data = {\n",
    "  'X_train': data['X_train'][:num_train],\n",
    "  'y_train': data['y_train'][:num_train],\n",
    "  'X_val': data['X_val'],\n",
    "  'y_val': data['y_val'],\n",
    "}\n",
    "\n",
    "learning_rate = 2e-3  # Experiment with this!\n",
    "weight_scale = 1e-5   # Experiment with this!\n",
    "model = FullyConnectedNet([100, 100, 100, 100],\n",
    "                weight_scale=weight_scale, dtype=np.float64)\n",
    "solver = Solver(model, small_data,\n",
    "                print_every=10, num_epochs=20, batch_size=25,\n",
    "                update_rule='sgd',\n",
    "                optim_config={\n",
    "                  'learning_rate': learning_rate,\n",
    "                }\n",
    "         )\n",
    "solver.train()\n",
    "\n",
    "plt.plot(solver.loss_history, 'o')\n",
    "plt.title('Training loss history')\n",
    "plt.xlabel('Iteration')\n",
    "plt.ylabel('Training loss')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "tags": [
     "pdf-inline"
    ]
   },
   "source": [
    "## Inline Question 2: \n",
    "Did you notice anything about the comparative difficulty of training the three-layer net vs training the five layer net? In particular, based on your experience, which network seemed more sensitive to the initialization scale? Why do you think that is the case?\n",
    "\n",
    "## Answer:\n",
    "[FILL THIS IN]\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Update rules\n",
    "So far we have used vanilla stochastic gradient descent (SGD) as our update rule. More sophisticated update rules can make it easier to train deep networks. We will implement a few of the most commonly used update rules and compare them to vanilla SGD."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# SGD+Momentum\n",
    "Stochastic gradient descent with momentum is a widely used update rule that tends to make deep networks converge faster than vanilla stochastic gradient descent. See the Momentum Update section at http://cs231n.github.io/neural-networks-3/#sgd for more information.\n",
    "\n",
    "Open the file `cs231n/optim.py` and read the documentation at the top of the file to make sure you understand the API. Implement the SGD+momentum update rule in the function `sgd_momentum` and run the following to check your implementation. You should see errors less than e-8."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from cs231n.optim import sgd_momentum\n",
    "\n",
    "N, D = 4, 5\n",
    "w = np.linspace(-0.4, 0.6, num=N*D).reshape(N, D)\n",
    "dw = np.linspace(-0.6, 0.4, num=N*D).reshape(N, D)\n",
    "v = np.linspace(0.6, 0.9, num=N*D).reshape(N, D)\n",
    "\n",
    "config = {'learning_rate': 1e-3, 'velocity': v}\n",
    "next_w, _ = sgd_momentum(w, dw, config=config)\n",
    "\n",
    "expected_next_w = np.asarray([\n",
    "  [ 0.1406,      0.20738947,  0.27417895,  0.34096842,  0.40775789],\n",
    "  [ 0.47454737,  0.54133684,  0.60812632,  0.67491579,  0.74170526],\n",
    "  [ 0.80849474,  0.87528421,  0.94207368,  1.00886316,  1.07565263],\n",
    "  [ 1.14244211,  1.20923158,  1.27602105,  1.34281053,  1.4096    ]])\n",
    "expected_velocity = np.asarray([\n",
    "  [ 0.5406,      0.55475789,  0.56891579, 0.58307368,  0.59723158],\n",
    "  [ 0.61138947,  0.62554737,  0.63970526,  0.65386316,  0.66802105],\n",
    "  [ 0.68217895,  0.69633684,  0.71049474,  0.72465263,  0.73881053],\n",
    "  [ 0.75296842,  0.76712632,  0.78128421,  0.79544211,  0.8096    ]])\n",
    "\n",
    "# Should see relative errors around e-8 or less\n",
    "print('next_w error: ', rel_error(next_w, expected_next_w))\n",
    "print('velocity error: ', rel_error(expected_velocity, config['velocity']))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Once you have done so, run the following to train a six-layer network with both SGD and SGD+momentum. You should see the SGD+momentum update rule converge faster."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "scrolled": false
   },
   "outputs": [],
   "source": [
    "num_train = 4000\n",
    "small_data = {\n",
    "  'X_train': data['X_train'][:num_train],\n",
    "  'y_train': data['y_train'][:num_train],\n",
    "  'X_val': data['X_val'],\n",
    "  'y_val': data['y_val'],\n",
    "}\n",
    "\n",
    "solvers = {}\n",
    "\n",
    "for update_rule in ['sgd', 'sgd_momentum']:\n",
    "  print('running with ', update_rule)\n",
    "  model = FullyConnectedNet([100, 100, 100, 100, 100], weight_scale=5e-2)\n",
    "\n",
    "  solver = Solver(model, small_data,\n",
    "                  num_epochs=5, batch_size=100,\n",
    "                  update_rule=update_rule,\n",
    "                  optim_config={\n",
    "                    'learning_rate': 5e-3,\n",
    "                  },\n",
    "                  verbose=True)\n",
    "  solvers[update_rule] = solver\n",
    "  solver.train()\n",
    "  print()\n",
    "\n",
    "plt.subplot(3, 1, 1)\n",
    "plt.title('Training loss')\n",
    "plt.xlabel('Iteration')\n",
    "\n",
    "plt.subplot(3, 1, 2)\n",
    "plt.title('Training accuracy')\n",
    "plt.xlabel('Epoch')\n",
    "\n",
    "plt.subplot(3, 1, 3)\n",
    "plt.title('Validation accuracy')\n",
    "plt.xlabel('Epoch')\n",
    "\n",
    "for update_rule, solver in solvers.items():\n",
    "  plt.subplot(3, 1, 1)\n",
    "  plt.plot(solver.loss_history, 'o', label=\"loss_%s\" % update_rule)\n",
    "  \n",
    "  plt.subplot(3, 1, 2)\n",
    "  plt.plot(solver.train_acc_history, '-o', label=\"train_acc_%s\" % update_rule)\n",
    "\n",
    "  plt.subplot(3, 1, 3)\n",
    "  plt.plot(solver.val_acc_history, '-o', label=\"val_acc_%s\" % update_rule)\n",
    "  \n",
    "for i in [1, 2, 3]:\n",
    "  plt.subplot(3, 1, i)\n",
    "  plt.legend(loc='upper center', ncol=4)\n",
    "plt.gcf().set_size_inches(15, 15)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# RMSProp and Adam\n",
    "RMSProp [1] and Adam [2] are update rules that set per-parameter learning rates by using a running average of the second moments of gradients.\n",
    "\n",
    "In the file `cs231n/optim.py`, implement the RMSProp update rule in the `rmsprop` function and implement the Adam update rule in the `adam` function, and check your implementations using the tests below.\n",
    "\n",
    "**NOTE:** Please implement the _complete_ Adam update rule (with the bias correction mechanism), not the first simplified version mentioned in the course notes. \n",
    "\n",
    "[1] Tijmen Tieleman and Geoffrey Hinton. \"Lecture 6.5-rmsprop: Divide the gradient by a running average of its recent magnitude.\" COURSERA: Neural Networks for Machine Learning 4 (2012).\n",
    "\n",
    "[2] Diederik Kingma and Jimmy Ba, \"Adam: A Method for Stochastic Optimization\", ICLR 2015."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Test RMSProp implementation\n",
    "from cs231n.optim import rmsprop\n",
    "\n",
    "N, D = 4, 5\n",
    "w = np.linspace(-0.4, 0.6, num=N*D).reshape(N, D)\n",
    "dw = np.linspace(-0.6, 0.4, num=N*D).reshape(N, D)\n",
    "cache = np.linspace(0.6, 0.9, num=N*D).reshape(N, D)\n",
    "\n",
    "config = {'learning_rate': 1e-2, 'cache': cache}\n",
    "next_w, _ = rmsprop(w, dw, config=config)\n",
    "\n",
    "expected_next_w = np.asarray([\n",
    "  [-0.39223849, -0.34037513, -0.28849239, -0.23659121, -0.18467247],\n",
    "  [-0.132737,   -0.08078555, -0.02881884,  0.02316247,  0.07515774],\n",
    "  [ 0.12716641,  0.17918792,  0.23122175,  0.28326742,  0.33532447],\n",
    "  [ 0.38739248,  0.43947102,  0.49155973,  0.54365823,  0.59576619]])\n",
    "expected_cache = np.asarray([\n",
    "  [ 0.5976,      0.6126277,   0.6277108,   0.64284931,  0.65804321],\n",
    "  [ 0.67329252,  0.68859723,  0.70395734,  0.71937285,  0.73484377],\n",
    "  [ 0.75037008,  0.7659518,   0.78158892,  0.79728144,  0.81302936],\n",
    "  [ 0.82883269,  0.84469141,  0.86060554,  0.87657507,  0.8926    ]])\n",
    "\n",
    "# You should see relative errors around e-7 or less\n",
    "print('next_w error: ', rel_error(expected_next_w, next_w))\n",
    "print('cache error: ', rel_error(expected_cache, config['cache']))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Test Adam implementation\n",
    "from cs231n.optim import adam\n",
    "\n",
    "N, D = 4, 5\n",
    "w = np.linspace(-0.4, 0.6, num=N*D).reshape(N, D)\n",
    "dw = np.linspace(-0.6, 0.4, num=N*D).reshape(N, D)\n",
    "m = np.linspace(0.6, 0.9, num=N*D).reshape(N, D)\n",
    "v = np.linspace(0.7, 0.5, num=N*D).reshape(N, D)\n",
    "\n",
    "config = {'learning_rate': 1e-2, 'm': m, 'v': v, 't': 5}\n",
    "next_w, _ = adam(w, dw, config=config)\n",
    "\n",
    "expected_next_w = np.asarray([\n",
    "  [-0.40094747, -0.34836187, -0.29577703, -0.24319299, -0.19060977],\n",
    "  [-0.1380274,  -0.08544591, -0.03286534,  0.01971428,  0.0722929],\n",
    "  [ 0.1248705,   0.17744702,  0.23002243,  0.28259667,  0.33516969],\n",
    "  [ 0.38774145,  0.44031188,  0.49288093,  0.54544852,  0.59801459]])\n",
    "expected_v = np.asarray([\n",
    "  [ 0.69966,     0.68908382,  0.67851319,  0.66794809,  0.65738853,],\n",
    "  [ 0.64683452,  0.63628604,  0.6257431,   0.61520571,  0.60467385,],\n",
    "  [ 0.59414753,  0.58362676,  0.57311152,  0.56260183,  0.55209767,],\n",
    "  [ 0.54159906,  0.53110598,  0.52061845,  0.51013645,  0.49966,   ]])\n",
    "expected_m = np.asarray([\n",
    "  [ 0.48,        0.49947368,  0.51894737,  0.53842105,  0.55789474],\n",
    "  [ 0.57736842,  0.59684211,  0.61631579,  0.63578947,  0.65526316],\n",
    "  [ 0.67473684,  0.69421053,  0.71368421,  0.73315789,  0.75263158],\n",
    "  [ 0.77210526,  0.79157895,  0.81105263,  0.83052632,  0.85      ]])\n",
    "\n",
    "# You should see relative errors around e-7 or less\n",
    "print('next_w error: ', rel_error(expected_next_w, next_w))\n",
    "print('v error: ', rel_error(expected_v, config['v']))\n",
    "print('m error: ', rel_error(expected_m, config['m']))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Once you have debugged your RMSProp and Adam implementations, run the following to train a pair of deep networks using these new update rules:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "learning_rates = {'rmsprop': 1e-4, 'adam': 1e-3}\n",
    "for update_rule in ['adam', 'rmsprop']:\n",
    "  print('running with ', update_rule)\n",
    "  model = FullyConnectedNet([100, 100, 100, 100, 100], weight_scale=5e-2)\n",
    "\n",
    "  solver = Solver(model, small_data,\n",
    "                  num_epochs=5, batch_size=100,\n",
    "                  update_rule=update_rule,\n",
    "                  optim_config={\n",
    "                    'learning_rate': learning_rates[update_rule]\n",
    "                  },\n",
    "                  verbose=True)\n",
    "  solvers[update_rule] = solver\n",
    "  solver.train()\n",
    "  print()\n",
    "\n",
    "plt.subplot(3, 1, 1)\n",
    "plt.title('Training loss')\n",
    "plt.xlabel('Iteration')\n",
    "\n",
    "plt.subplot(3, 1, 2)\n",
    "plt.title('Training accuracy')\n",
    "plt.xlabel('Epoch')\n",
    "\n",
    "plt.subplot(3, 1, 3)\n",
    "plt.title('Validation accuracy')\n",
    "plt.xlabel('Epoch')\n",
    "\n",
    "for update_rule, solver in list(solvers.items()):\n",
    "  plt.subplot(3, 1, 1)\n",
    "  plt.plot(solver.loss_history, 'o', label=update_rule)\n",
    "  \n",
    "  plt.subplot(3, 1, 2)\n",
    "  plt.plot(solver.train_acc_history, '-o', label=update_rule)\n",
    "\n",
    "  plt.subplot(3, 1, 3)\n",
    "  plt.plot(solver.val_acc_history, '-o', label=update_rule)\n",
    "  \n",
    "for i in [1, 2, 3]:\n",
    "  plt.subplot(3, 1, i)\n",
    "  plt.legend(loc='upper center', ncol=4)\n",
    "plt.gcf().set_size_inches(15, 15)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "tags": [
     "pdf-inline"
    ]
   },
   "source": [
    "## Inline Question 3:\n",
    "\n",
    "AdaGrad, like Adam, is a per-parameter optimization method that uses the following update rule:\n",
    "\n",
    "```\n",
    "cache += dw**2\n",
    "w += - learning_rate * dw / (np.sqrt(cache) + eps)\n",
    "```\n",
    "\n",
    "John notices that when he was training a network with AdaGrad that the updates became very small, and that his network was learning slowly. Using your knowledge of the AdaGrad update rule, why do you think the updates would become very small? Would Adam have the same issue?\n",
    "\n",
    "\n",
    "## Answer: \n",
    "[FILL THIS IN]\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Train a good model!\n",
    "Train the best fully-connected model that you can on CIFAR-10, storing your best model in the `best_model` variable. We require you to get at least 50% accuracy on the validation set using a fully-connected net.\n",
    "\n",
    "If you are careful it should be possible to get accuracies above 55%, but we don't require it for this part and won't assign extra credit for doing so. Later in the assignment we will ask you to train the best convolutional network that you can on CIFAR-10, and we would prefer that you spend your effort working on convolutional nets rather than fully-connected nets.\n",
    "\n",
    "You might find it useful to complete the `BatchNormalization.ipynb` and `Dropout.ipynb` notebooks before completing this part, since those techniques can help you train powerful models."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "scrolled": false
   },
   "outputs": [],
   "source": [
    "best_model = None\n",
    "################################################################################\n",
    "# TODO: Train the best FullyConnectedNet that you can on CIFAR-10. You might   #\n",
    "# find batch/layer normalization and dropout useful. Store your best model in  #\n",
    "# the best_model variable.                                                     #\n",
    "################################################################################\n",
    "# *****START OF YOUR CODE (DO NOT DELETE/MODIFY THIS LINE)*****\n",
    "\n",
    "pass\n",
    "\n",
    "# *****END OF YOUR CODE (DO NOT DELETE/MODIFY THIS LINE)*****\n",
    "################################################################################\n",
    "#                              END OF YOUR CODE                                #\n",
    "################################################################################"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Test your model!\n",
    "Run your best model on the validation and test sets. You should achieve above 50% accuracy on the validation set."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "y_test_pred = np.argmax(best_model.loss(data['X_test']), axis=1)\n",
    "y_val_pred = np.argmax(best_model.loss(data['X_val']), axis=1)\n",
    "print('Validation set accuracy: ', (y_val_pred == data['y_val']).mean())\n",
    "print('Test set accuracy: ', (y_test_pred == data['y_test']).mean())"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
